package com.neuedu.linkedlist;

import java.util.Iterator;

public class SinglyLinkedList implements Iterable<Integer> {
    private Node head;

    private static class Node{//如果内部类没有用到外部类的成员，它可以加static
        int value;
        Node next;

        public Node(int value, Node next) {
            this.value = value;
            this.next = next;
        }
    }

    private class NodeIterator implements Iterator<Integer>{
        Node cur = head;
        @Override
        public boolean hasNext() {
            return cur!=null;
        }

        @Override
        public Integer next() {
            Integer value = cur.value;
            cur = cur.next;
            return value;
        }
    }

    public Iterator<Integer> iterator() {
        return new NodeIterator();
    }

    public void addFirst(int value){//如果链表不为空，新节点的next指向原链表
        this.head = new Node(value,this.head);
    }

    private Node findLast(){
        if (this.head == null){
            return null;
        }
        Node cur;//当前指针
        for(cur = this.head ; cur.next != null ;){//cur指针 = head头结点，条件指针下一节点不为空
            cur = cur.next;
        }
        return cur;
    }

    public void addLast(int value){
        Node last = findLast();
        if (last == null){
            addFirst(value);
            return;
        }
        last.next = new Node(value,null);
    }

    public void addLast(int first , int ...rest){
        Node subList = new Node(first,null);
        Node cur = subList;
        for(int value : rest){
            cur.next = new Node(value,null);
            cur = cur.next;
        }
        Node last = findLast();
        if (last == null){
            this.head = subList;
            return;
        }
        last.next = subList;
    }

    //refactor->Extract Method可以抽取成一个方法
    private IllegalArgumentException illegalIndex(int index){//%d整数类型的占位符,%n换行
        throw new IllegalArgumentException(String.format("index[%d]不合法%n",index));
    }

    public Node findNode(int index){
        int i = 0;
        for (Node cur = this.head ; cur.next != null ; cur = cur.next ,i++){
            if (index == i){
                return cur;
            }
        }
        return null;
    }

    public int get(int index){
        Node node = findNode(index);
        if (node != null){
            return node.value;
        }
        throw illegalIndex(index);
    }

    /**
     * 向指定索引位置添加节点
     * @param index
     * @param value
     */
    public void insert(int index , int value){
        if (index == 0){
            addFirst(value);
            return;
        }
        Node prev = findNode(index - 1);//因为没有加哨兵，找不到节点会返回null
        //情况1：链表只有4个元素，要插入到索引为10
        if (prev == null){
            throw illegalIndex(index);
        }
        prev.next = new Node(value,prev.next);
    }

    /**
     * 删除头部节点
     */
    public void removeFirst(){//没有引用的节点，会被垃圾回收机制回收(java)
        if (head == null){//当链表中无元素时，抛出异常
            throw illegalIndex(0);
        }
        head = head.next;
    }


}
